package com.heima.se.sjms.单例.不安全单例;

/*
    单例模式： 一个类始终只产生一个对象使用。
    注意：常规的单例很容易被破坏，破坏单例常用技术手段： 暴力反射， 序列化操作
 */

import java.io.*;
import java.lang.reflect.Constructor;

public class Demo {
    public static Student stu;

    public static void main(String[] args) throws Exception {

        Student stu1 = getStu();
        System.out.println("stu1 = " + stu1);

        Student stu2 = getStu();
        System.out.println("stu2 = " + stu2);

        //暴力反射破坏单例
        Class clazz = stu1.getClass();
        Constructor constructor = clazz.getDeclaredConstructor();
        constructor.setAccessible(true);
        Student stu3 = (Student) constructor.newInstance();
        System.out.println("stu3 = " + stu3);

        //序列化操作破坏单例
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:\\IdeaProjects\\heima-leadnews\\heima-leadnews-test\\javaSE-demo\\src\\main\\resources\\stu.txt"));
        oos.writeObject(stu1);          //序列化
        oos.close();

        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:\\IdeaProjects\\heima-leadnews\\heima-leadnews-test\\javaSE-demo\\src\\main\\resources\\stu.txt"));
        Student stu4 = (Student) ois.readObject();      //反序列化
        ois.close();
        System.out.println("stu4 = " + stu4);
    }

    //懒汉式  -- 延迟加载。
    public static Student getStu() {
        synchronized ("abc") {
            if (stu == null) {
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                stu = new Student();
            }
        }
        return stu;
    }
}

class Student implements Serializable {
}
